package com.bsoft.gol.hcb.service.accessAuth;

import com.bsoft.gol.hcb.dao.accessAuth.AcApplyRecordDAO;
import com.bsoft.gol.hcb.dao.accessAuth.AcDoctorAuthDAO;
import com.bsoft.gol.hcb.service.accessAuth.dto.AuthPatientInfoDto;
import com.bsoft.gol.hcb.service.accessAuth.vo.AuthPatientInfoVo;
import com.bsoft.gol.hcb.utils.BeanUtil;
import com.bsoft.gol.hcb.utils.CommonUtils;
import com.bsoft.gol.hcb.utils.Constants;
import com.bsoft.gol.hcb.utils.DateUtils;
import com.bsoft.gol.mpi.model.Person;
import com.bsoft.gol.mpi.model.Unique;
import com.bsoft.gol.mpi.provider.IMPIProvider;
import com.bsoft.gol.mpi.service.MPIException;
import com.security.cipher.sm.SM4Utils;
import ctd.controller.exception.ControllerException;
import ctd.net.rpc.Client;
import ctd.spring.boot.annotation.SsdevReference;
import ctd.spring.boot.annotation.SsdevService;
import ctd.util.JSONUtils;
import ctd.util.KeyGenerator;
import ctd.util.annotation.RpcService;
import hcn.api.service.api.inpatient.InpatientService;
import hcn.base.BasePropertyConfig;
import hcn.base.Notification;
import hcn.base.Organization;
import hcn.base.UserPreference;
import hcn.base.accessAuth.AcApplyRecordEntity;
import hcn.base.accessAuth.AcDoctorAuthEntity;
import hcn.base.notification.event.NotificationEvent;
import hcn.base.register.ISmsService;
import hcn.bean.PushMessageBean;
import hcn.bean.UserAllVo;
import hcn.enums.MsgTemplateCode;
import hcn.protocol.registration.QueryPatientListVO;
import hcn.protocol.registration.xml.req.QueryPatientListQO;
import hcn.service.accessauth.AccessAuthService;
import hcn.service.accessauth.request.CancelAuthRequest;
import hcn.service.accessauth.request.DSmsVerifyResquest;
import hcn.service.accessauth.request.DoctorAccessRequest;
import hcn.service.accessauth.request.InitiativeAuthRequest;
import hcn.service.accessauth.request.ResidentAuditRequest;
import hcn.service.accessauth.response.ResourceAuthResponse;
import hcn.service.base.IDoctorService;
import hcn.service.base.IOrganizationService;
import hcn.service.notification.INotificationService;
import hcn.util.PageInfo;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.atag.core.exception.ServiceException;
import org.atag.util.event.MessageSendEventManager;
import org.atag.util.event.support.MessageSendEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import pcn.enums.RoleIdEnum;
import pcn.service.web.BaseDeviceService;
@SsdevService("accessAuth")
public class AccessAuthServiceImpl implements AccessAuthService {
    private final static Logger logger = LoggerFactory.getLogger(AccessAuthServiceImpl.class);

    @Autowired
    private AcApplyRecordDAO acApplyRecordDAO;
    @Autowired
    private AcDoctorAuthDAO acDoctorAuthDAO;
    @SsdevReference("gol-mpi.mpiProvider")
    private IMPIProvider hcnMpiProvider;
    @SsdevReference("hcn.smsService")
    private ISmsService smsService;
    @SsdevReference("hcn.baseDeviceService")
    private BaseDeviceService baseDeviceService;
    @SsdevReference("hcn.doctor")
    private IDoctorService doctorService;
    @SsdevReference("hcn.notification")
    private INotificationService notificationService;
    @Autowired
    private MessageSendEventManager messageSendEventManager;
    @SsdevReference("hcnInterface.inpatientService")
    private InpatientService inpatientService;
    @SsdevReference("hcn.organization")
    private IOrganizationService organizationService;

//    private SmsLoaderCache smsLoaderCache;


    /**
     * 医生获取问患者资源权限
     *
     * @param request
     * @return
     */
    @Override
    @RpcService
    public ResourceAuthResponse doctorResourceAuth(DoctorAccessRequest request) {
        UserAllVo userAllVo = baseDeviceService.getAllByOnline();
        setBaseParam(request, userAllVo);
        ResourceAuthResponse response = new ResourceAuthResponse();
        response.setAccountFlag(true);
        //系统是否开启授权，0-不开启 1-开启
        try {
            BasePropertyConfig basePropertyConfig = (BasePropertyConfig) Client.rpcInvoke("hbs.basePropertyConfig", "getPropertyConfigByPropertyCode", "012904", request.getOrgId());
            String propertyData = basePropertyConfig.getPropertyData();
            if ("0".equals(propertyData)) {
                response.setState("1");
                return response;
            }
        } catch (Exception e) {
            logger.error("获取系统参数失败", e);
        }

        //查询是否单条授权 0-全部授权 1-单条授权
        boolean fullAuth = true;
        String resourceId = "";
        try {
            Unique masterUnique = null;
            try {
                masterUnique = hcnMpiProvider.getUnique(request.getMpiId(), Constants.USERID_SOURCE, Constants.USERID_TYPE_CODE);
            }catch (Exception e){
                logger.info("查询主账户信息出错：" + e.getMessage());
            }
            if(null!= masterUnique){
                String tenantId = request.getTenantId();
                String userId = SM4Utils.decryptData_ECB(masterUnique.getUniqueId());
                String roleId = "patient";

                logger.info("tenantId:" + tenantId + ",userId:" + userId + ",roleId:" + roleId);
                UserPreference byUserIdAndRoleId = (UserPreference) Client.rpcInvoke("hcn.userPreferenceDao", "getByUserIdAndRoleId", tenantId, userId, roleId);

                if (CommonUtils.isNotEmpty(byUserIdAndRoleId)) {
                    logger.info("+++++++=========++++++++++用户授权开关："+byUserIdAndRoleId.getAccessAuthSwitch());
                    if ("1".equals(byUserIdAndRoleId.getAccessAuthSwitch())) {//开-单条
                        fullAuth = false;
                        resourceId = request.getResourceId();
                    }
                }else {
                    logger.info("++++++++++++++++++++==============+++++++用户授权开关查不到");
                }
            } else{
                response.setAccountFlag(false);
            }
            logger.info("单条授权是否关闭："+fullAuth+"，resourceId："+resourceId);
            if(!fullAuth){
                List<AcDoctorAuthEntity> entityList = acDoctorAuthDAO.queryAcDoctorAuthOne(resourceId, request.getUserId(), request.getMpiId(),
                        request.getBizType(), request.getResourceType(), "2",new Date());
                if (CommonUtils.isNotEmpty(entityList)) {//存在
                    String state = "1";//有效时间内直接返回有效
                    response.setState(state);
                } else {
                    //不全和单条都没有，查记录表是否有在审核的
                    AcApplyRecordEntity caEntity = acApplyRecordDAO.getAAROrdByutime(request.getMpiId(), resourceId,
                            request.getResourceType(),request.getBizType(), request.getUserId(), "2");
                    if (CommonUtils.isNotEmpty(caEntity)) {//存在
                        String state = caEntity.getApplyState() == null ? "0" : caEntity.getApplyState();
                        if("1".equals(caEntity.getApplyState())){// 过期有效
                            state = "0";
                        }
                        response.setState(state);
                    } else {//不存在 没权限
                        String state = "0";
                        response.setState(state);
                    }
                }
            }else{
                List<AcDoctorAuthEntity> entitList = acDoctorAuthDAO.queryAcDoctorAuth(request.getUserId(), request.getMpiId(),
                        request.getBizType(), request.getResourceType(), "1",new Date());
                if (CommonUtils.isNotEmpty(entitList)) {//已存在则直接返回
                    String state = "1";//有效时间内直接返回有效
                    response.setState(state);

                }else {//不全和单条都没有，查记录表是否有在审核的
                    //查最新的一条
                    AcApplyRecordEntity caEntity = acApplyRecordDAO.getAAROrdByutime(request.getMpiId(), resourceId,
                            request.getResourceType(),request.getBizType(), request.getUserId(), "1");
                    if (CommonUtils.isNotEmpty(caEntity)) {//存在
                        String state = caEntity.getApplyState() == null ? "0" : caEntity.getApplyState();
                        if("1".equals(caEntity.getApplyState())){// 过期有效
                            state = "0";
                        }
                        response.setState(state);
                    } else {//不存在 没权限
                        String state = "0";
                        response.setState(state);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("个人授权信息查询出错：" + e.getMessage());
            throw new ServiceException("个人授权信息查询出错");
        }

        return response;
    }

    /**
     * 医生发起调阅申请
     *
     * @param request
     * @return
     */
    @Override
    @RpcService
    public void doctorAccessRequest(DoctorAccessRequest request) throws ControllerException {
        UserAllVo userAllVo = baseDeviceService.getAllByOnline();
        setBaseParam(request, userAllVo);
        String recordId = KeyGenerator.randomGenerate();
        String patientName = "";
        String doctorName = "";
        //1.查询患者信息
        try {
            Person person = hcnMpiProvider.getPerson(request.getMpiId());
//            Unique q = ContextHelper.createUserUnique(request.getUserId());
//            Person doctorPerson = hcnMpiProvider.getPersonByUnique(q);
            if(person == null){
                throw new ServiceException("查询不到当前患者信息");
            }
            patientName = person.getPersonName();
            doctorName = userAllVo.getUserName();
        } catch (MPIException e) {
            logger.error("获取用户信息失败", e);
            throw new ControllerException("获取用户信息失败");
        }

        //2.查询用户单条授权开关
        String AccessAuthSwitch = "1";//全部授权 1-就诊人维度 2-业务数据维度
        try {
            Unique masterUnique = null;
            masterUnique = hcnMpiProvider.getUnique(request.getMpiId(), Constants.USERID_SOURCE, Constants.USERID_TYPE_CODE);
            if(null!= masterUnique){
                String tenantId = request.getTenantId();
                String userId = SM4Utils.decryptData_ECB(masterUnique.getUniqueId());
                String roleId = "patient";
                logger.info("tenantId:" + tenantId + ",userId:" + userId + ",roleId:" + roleId);
                UserPreference byUserIdAndRoleId = (UserPreference) Client.rpcInvoke("hcn.userPreferenceDao", "getByUserIdAndRoleId", tenantId, userId, roleId);

                if (CommonUtils.isNotEmpty(byUserIdAndRoleId)) {
                    logger.info("+++++++=========++++++++++用户授权开关：" + byUserIdAndRoleId.getAccessAuthSwitch());
                    if ("1".equals(byUserIdAndRoleId.getAccessAuthSwitch())) {//开-单条
                        AccessAuthSwitch = "2";//单条授权 1-就诊人维度 2-业务数据维度
                        logger.info("++===========AccessAuthSwitch：" + AccessAuthSwitch);
                    }
                }
            }

        }catch (Exception e) {
            logger.error("个人授权信息查询出错：" + e.getMessage());
            throw new ServiceException("个人授权信息查询出错");
        }
        logger.info("++===========AccessAuthSwitch：" + AccessAuthSwitch);

        //3.是否有在途的申请中数据
        String resourceId = request.getResourceId();
        if("1".equals(AccessAuthSwitch)){//全部授权的时候 resourceId 赋空
            resourceId = "";
        }
        AcApplyRecordEntity caEntity = acApplyRecordDAO.getAARByState(request.getMpiId(), resourceId, request.getResourceType(), request.getBizType(), request.getUserId(), "1",AccessAuthSwitch,"2" );
        if (CommonUtils.isNotEmpty(caEntity)) {//存在
            throw new ServiceException("存在申请中的数据，不允许重复发起");
        }

        //4."调阅授权申请记录"插入一条申请中数据
        AcApplyRecordEntity entity = new AcApplyRecordEntity();
        BeanUtil.copyProperties(request, entity);
//        AcApplyRecordEntity caEntity = acApplyRecordDAO.getAcApplyRecord(request.getMpiId(), request.getResourceId(), request.getResourceType(), request.getBizType(), request.getUserId(), "1",AccessAuthSwitch );
//        if (CommonUtils.isNotEmpty(caEntity)) {//存在 更新
//            recordId = caEntity.getRecordId();//这里的recordID和前面重复
//            entity.setRecordId(recordId);
////            entity.setAuthType(AccessAuthSwitch);
//            entity.setApplyState("2");//申请中 1-申请通过 2-申请中 3-申请失败
//            entity.setUpdateName(doctorName);//医生名
//            entity.setUpdateTime(new Date());
//            acApplyRecordDAO.updateSelective(entity);
//
//        } else {//不存在 插入
            entity.setResourceId(resourceId);
            entity.setAuthType(AccessAuthSwitch);
            entity.setRecordId(recordId);
            entity.setApplyId(request.getUserId());
            entity.setApplyName(doctorName);//根据userid获取医生名
            entity.setApplyType("1");//医生申请
            entity.setApplyState("2");//申请中 1-申请通过 2-申请中 3-申请失败
            entity.setCreateName(doctorName);//医生名
            entity.setCreateTime(new Date());
            entity.setUpdateName(doctorName);//医生名
            entity.setUpdateTime(new Date());
            acApplyRecordDAO.save(entity);
//        }

        //5.发送极光信息
        logger.info("doctorAccessRequest,调用授权推送消息开始++++++++++++++++++++++++++++++++++++");
        List<Map<String, Object>> userIdList = null;
        try {
            userIdList = (List<Map<String, Object>>) Client.rpcInvoke("pcn.baseUserManageUnitService", "queryPatientsInfoById", request.getMpiId());
        } catch (Throwable throwable) {
            logger.error("获取用户信息失败", throwable);
            throw new ServiceException("pcn.baseUserManageUnitService,queryPatientsInfoById调用失败！");
        }
        if (userIdList.size() > 0) {//不空发消息
            for (Map<String, Object> data : userIdList) {
                String userid = (String) data.get("userId");
                //a.调用消息通知
                PushMessageBean pushMessageBean = new PushMessageBean();
                pushMessageBean.setRoleId(RoleIdEnum.PATIENT.title());
                //消息通知大类小类
                pushMessageBean.setNotificateType(String.valueOf(NotificationEvent.NotificateType.patient_Authorization_of_access));
                //配置模板code
                pushMessageBean.setTemplateCode(MsgTemplateCode.PATIENT_AUTHORIZATION_OF_ACCESS.getCode());
//                pushMessageBean.setUserId(request.getHUserId());
                pushMessageBean.setUserId(userid);
                Map<String, String> variableMap = new HashMap<String, String>();

                variableMap.put("#患者姓名#", patientName);
                variableMap.put("#医生姓名#", doctorName);
                pushMessageBean.setMsgVariableMap(variableMap);

                Map<String, String> extras = new HashMap<String, String>();
                extras.put("recordId", recordId);
                extras.put("state", "2");
                extras.put("localOrgId", userAllVo.getLocalOrgId());
                extras.put("doctorId", userAllVo.getDoctorId());
                extras.put("localDoctorId", userAllVo.getLocalDoctorId());
                extras.put("doctorLoginName", userAllVo.getLoginName());
                extras.put("doctorName", doctorName);
                extras.put("roleId", userAllVo.getRoleId());
                extras.put("roleName", userAllVo.getRoleName());
                pushMessageBean.setExtras(extras);
                messageSendEventManager.fireEvent(new MessageSendEvent(pushMessageBean), true);
            }
        }
        logger.info("doctorAccessRequest,调用授权推送消息结束++++++++++++++++++++++++++++++++++++" + patientName + ",---" + doctorName);

    }

    /**
     * 医生发送调阅验证码 todo 返回对应的recordId
     *
     * @param request
     * @return
     * @throws ControllerException
     */
    @Override
    @RpcService
    public String doctorSmsAccessRequest(DoctorAccessRequest request) throws ControllerException {
        //1.发送短信验证码
        //String tenantId, String roleId, String phoneNo, String type, String verifyCode
        smsService.getIdentifyingCode(request.getTenantId(), "", request.getPhone(), "AuthorizationAccess", request.getVerifyCode());
//        b."调阅授权申请记录"插入一条申请中数据
        //2.获取登录医生信息

        UserAllVo userAllVo = baseDeviceService.getAllByOnline();
        setBaseParam(request, userAllVo);
        //3.获取用户授权开关
        String AccessAuthSwitch = "1";//全部授权 1-就诊人维度 2-业务数据维度
        try {
            Unique masterUnique = null;
            masterUnique = hcnMpiProvider.getUnique(request.getMpiId(), Constants.USERID_SOURCE, Constants.USERID_TYPE_CODE);
            if(null!= masterUnique){
                String tenantId = request.getTenantId();
                String userId = SM4Utils.decryptData_ECB(masterUnique.getUniqueId());
                String roleId = "patient";
                logger.info("tenantId:" + tenantId + ",userId:" + userId + ",roleId:" + roleId);
                UserPreference byUserIdAndRoleId = (UserPreference) Client.rpcInvoke("hcn.userPreferenceDao", "getByUserIdAndRoleId", tenantId, userId, roleId);

                if (CommonUtils.isNotEmpty(byUserIdAndRoleId)) {
                    logger.info("+++++++=========++++++++++用户授权开关：" + byUserIdAndRoleId.getAccessAuthSwitch());
                    if ("1".equals(byUserIdAndRoleId.getAccessAuthSwitch())) {//开-单条
                        AccessAuthSwitch = "2";//单条授权 1-就诊人维度 2-业务数据维度
                        logger.info("++===========AccessAuthSwitch：" + AccessAuthSwitch);
                    }
                }
            }

        }catch (Exception e) {
            logger.error("个人授权信息查询出错：" + e.getMessage());
            throw new ServiceException("个人授权信息查询出错");
        }
        logger.info("++===========AccessAuthSwitch：" + AccessAuthSwitch);

        //4.是否有在途的申请中数据
        String resourceId = request.getResourceId();
        if("1".equals(AccessAuthSwitch)){//全部授权的时候 resourceId 赋空
            resourceId = "";
        }
        //短信可以重复多次发起
//        AcApplyRecordEntity caEntity = acApplyRecordDAO.getAARByState(request.getMpiId(), resourceId, request.getResourceType(), request.getBizType(), request.getUserId(), "1",AccessAuthSwitch,"2" );
//        if (CommonUtils.isNotEmpty(caEntity)) {//存在
//            throw new ServiceException("存在申请中的数据，不允许重复发起");
//        }

        //5.插入一条申请中数据
        AcApplyRecordEntity entity = new AcApplyRecordEntity();
        BeanUtil.copyProperties(request, entity);
        String recordId = KeyGenerator.randomGenerate();
//        AcApplyRecordEntity caEntity = acApplyRecordDAO.getAcApplyRecord(request.getMpiId(), request.getResourceId(), request.getResourceType(), request.getBizType(), userAllVo.getUserId(), "1",AccessAuthSwitch );
//        if (CommonUtils.isNotEmpty(caEntity)) {//存在 更新
//            recordId = caEntity.getRecordId();
//            entity.setRecordId(recordId);
////            entity.setAuthType(AccessAuthSwitch);
//            entity.setApplyState("2");//申请中 1-申请通过 2-申请中 3-申请失败
//            entity.setUpdateName(userAllVo.getUserName());//医生名
//            entity.setUpdateTime(new Date());
//            acApplyRecordDAO.updateSelective(entity);
//        }else{
            entity.setResourceId(resourceId);
            entity.setAuthType(AccessAuthSwitch);
            entity.setRecordId(recordId);
            entity.setApplyId(userAllVo.getUserId());
            entity.setApplyName(userAllVo.getUserName());//根据userid获取医生名
            entity.setApplyType("3");//医生短信申请
            entity.setApplyState("2");//申请中 1-申请通过 2-申请中 3-申请失败
            entity.setCreateName(userAllVo.getUserName());//医生名
            entity.setCreateTime(new Date());
            entity.setUpdateName(userAllVo.getUserName());//医生名
            entity.setUpdateTime(new Date());
            acApplyRecordDAO.save(entity);
//        }

        return recordId;
    }

    /**
     * 设置基础参数,如果前端未传值,则从当前登录人信息中去取
     */
    private void setBaseParam(DoctorAccessRequest request, UserAllVo userAllVo) {
        if(StringUtils.isEmpty(request.getTenantId())) {
            request.setTenantId(userAllVo.getTenantId());
        }
        if(StringUtils.isEmpty(request.getOrgId())) {
            request.setOrgId(userAllVo.getOrgId());
        }
        if(StringUtils.isEmpty(request.getDoctorId())) {
            request.setDoctorId(userAllVo.getDoctorId());
        }
        if(StringUtils.isEmpty(request.getUserId())) {
            request.setUserId(userAllVo.getUserId());
        }
    }

    /**
     * 医生验证患者验证码并获取授权
     *
     * @param request
     * @return
     */
    @Override
    @RpcService
    public void doctorSmsVerify(DSmsVerifyResquest request) throws ControllerException {
        //验证码校验
        boolean valid = smsService.validateCodeV2(request.getPhone(), request.getCaptcha(), "AuthorizationAccess");
        if (!valid) {
            throw new ServiceException("验证码无效");
        }

        //获取登录医生信息
        UserAllVo userAllVo = baseDeviceService.getAllByOnline();
        //b."调阅授权申请记录"申请中 更改 申请通过
        AcApplyRecordEntity entity = acApplyRecordDAO.get(request.getRecordId());
        if(!"2".equals(entity.getApplyState())){//申请中
            throw new ServiceException("该条记录不是在申请中状态");
        }
        if (CommonUtils.isNotEmpty(entity)) {
            AcApplyRecordEntity upentity = new AcApplyRecordEntity();
            BeanUtil.copyProperties(entity, upentity);
            String authId = KeyGenerator.randomGenerate();
            upentity.setAuthId(authId);
            upentity.setUpdateTime(new Date());
            upentity.setApplyState("1");//申请通过 1-申请通过 2-申请中 3-申请失败
            acApplyRecordDAO.update(upentity);
            //c.“医生调用授权表” 插入数据
            AcDoctorAuthEntity acentity = new AcDoctorAuthEntity();
            BeanUtil.copyProperties(entity, acentity);
            acentity.setAuthId(authId);
//            医生id获取
            acentity.setDoctorId(userAllVo.getDoctorId());
            acentity.setUserId(userAllVo.getUserId());
            if("1".equals(entity.getAuthType())){
                acentity.setAuthType("");
            }
//            acentity.setAuthType("2");//单条授权 1-就诊人维度 2-业务数据维度
//            授权时间计算，参数获取
            BasePropertyConfig basePropertyConfig = null;
            try {
                basePropertyConfig = (BasePropertyConfig) Client.rpcInvoke("hbs.basePropertyConfig", "getPropertyConfigByPropertyCode", "012905", entity.getOrgId());
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            if (basePropertyConfig == null) {
                throw new ServiceException("未找到授权有效期配置");
            }
            try {
                int minutes = Integer.parseInt(basePropertyConfig.getPropertyData());
                acentity.setAuthExpireTime(DateUtils.addDateMinute(minutes));//授权时间
            } catch (NumberFormatException e) {
                throw new ServiceException("字符串转数字失败：" + basePropertyConfig.getPropertyData());
            }

            acentity.setAuthActive("0");//有效
            acentity.setCreateTime(new Date());
            acentity.setUpdateTime(new Date());
            acDoctorAuthDAO.save(acentity);


        }
    }

    /**
     * 居民审核接口
     *
     * @param request
     * @return
     */
    @Override
    @RpcService
    public void residentAudit(ResidentAuditRequest request) {
//        认证类型 1-就诊人维度 2-业务数据维度  不需要吧
        //a."调阅授权申请记录"申请中 更改 申请通过
        //b.“医生调用授权表” 插入数据

        AcApplyRecordEntity entity = acApplyRecordDAO.get(request.getRecordId());
        if (CommonUtils.isEmpty(entity)) {
            throw new ServiceException("对应的申请数据不存在");
        }
        if(!"2".equals(entity.getApplyState())){//申请中
            throw new ServiceException("该条记录不是在申请中状态");
        }
        //存在
        if ("3".equals(request.getApplyState())) {//拒绝
            AcApplyRecordEntity upentity = new AcApplyRecordEntity();
            String authId = KeyGenerator.randomGenerate();
            upentity.setAuthId(authId);
            upentity.setUpdateTime(new Date());
            upentity.setApplyState("3");//申请失败
            upentity.setRecordId(request.getRecordId());
            acApplyRecordDAO.updateSelective(upentity);

        } else if ("1".equals(request.getApplyState())) {//同意
            //b."调阅授权申请记录"申请中 更改 申请通过
            AcApplyRecordEntity upentity = new AcApplyRecordEntity();
            String authId = KeyGenerator.randomGenerate();
            upentity.setAuthId(authId);
            upentity.setUpdateTime(new Date());
            upentity.setApplyState("1");//申请通过 1-申请通过 2-申请中 3-申请失败
            upentity.setRecordId(request.getRecordId());
            acApplyRecordDAO.updateSelective(upentity);
            //c.“医生调用授权表” 插入数据
            AcDoctorAuthEntity acentity = new AcDoctorAuthEntity();
            BeanUtil.copyProperties(entity, acentity);
            acentity.setAuthId(authId);
//                医生id获取
            String applyId = entity.getApplyId();
            //根据userId获取doctorId
            String doctorId = doctorService.getDoctorIdByUserId(applyId);
            acentity.setDoctorId(doctorId);//??????
            acentity.setUserId(applyId);
            acentity.setAuthType(entity.getAuthType());//单条授权 1-就诊人维度 2-业务数据维度
            if("1".equals(entity.getAuthType())){//全部授权
                acentity.setResourceId("");
            }

//                授权时间计算，参数获取
//            acentity.setAuthExpireTime(DateUtils.addDatehour(1));//授权时间
            BasePropertyConfig basePropertyConfig = null;
            try {
                basePropertyConfig = (BasePropertyConfig) Client.rpcInvoke("hbs.basePropertyConfig", "getPropertyConfigByPropertyCode", "012905", entity.getOrgId());
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
            if (basePropertyConfig == null) {
                throw new ServiceException("未找到授权有效期配置");
            }
            try {
                int minutes = Integer.parseInt(basePropertyConfig.getPropertyData());
                acentity.setAuthExpireTime(DateUtils.addDateMinute(minutes));//授权时间
            } catch (NumberFormatException e) {
                throw new ServiceException("字符串转数字失败：" + basePropertyConfig.getPropertyData());
            }

            acentity.setAuthActive("0");//有效
            acentity.setCreateTime(new Date());
            acentity.setUpdateTime(new Date());
            acDoctorAuthDAO.save(acentity);

        } else {
            throw new ServiceException("申请状态有误,请检查");
        }
        Integer notificationId = request.getNotificationId();
        try {
            Notification notification = notificationService.getById(notificationId);
            if(Objects.nonNull(notification)){
                String extras = notification.getExtras();
                Map parse = JSONUtils.parse(extras, Map.class);
                parse.put("state", request.getApplyState());
                String newExtras = JSONUtils.toString(parse);
                notificationService.updateNotificationExtras(notificationId, newExtras);
            }
        }catch (Exception e){
            logger.error("更新消息状态失败");
        }

    }

    /**
     * 主动授权
     */
    @Override
    public void initiativeAuth(InitiativeAuthRequest request) {

        AcDoctorAuthEntity authInsert = new AcDoctorAuthEntity();
        String authId = KeyGenerator.randomGenerate();
        authInsert.setAuthId(authId);
        authInsert.setTenantId(request.getTenantId());
        authInsert.setOrgId(request.getOrgId());
        authInsert.setMpiId(request.getMpiId());
        authInsert.setResourceType("0");
        authInsert.setBizId(request.getBizId());
        authInsert.setBizType(request.getBizType());
        authInsert.setAuthType(request.getAuthType());
        authInsert.setAuthExpireTime(request.getAuthExpireTime());
        authInsert.setAuthActive("1");
        authInsert.setCreateTime(new Date());
        authInsert.setUpdateTime(new Date());
        acDoctorAuthDAO.insertSelective(authInsert);

        AcApplyRecordEntity recordInsert = new AcApplyRecordEntity();
        recordInsert.setRecordId(KeyGenerator.randomGenerate());
        recordInsert.setTenantId(request.getTenantId());
        recordInsert.setAuthId(authId);
        recordInsert.setOrgId(request.getOrgId());
        recordInsert.setMpiId(request.getMpiId());
        recordInsert.setResourceType("0");
        recordInsert.setBizId(request.getBizId());
        recordInsert.setBizType(request.getBizType());
        recordInsert.setApplyId(request.getApplyId());
        recordInsert.setApplyName(request.getApplyName());
        recordInsert.setApplyType("2");
        recordInsert.setApplyState("1");//申请通 1-申请通过 2-申请中 3-申请失败
        recordInsert.setCreateName(request.getApplyName());
        recordInsert.setCreateTime(new Date());
        recordInsert.setUpdateName(request.getApplyName());
        recordInsert.setUpdateTime(new Date());

        acApplyRecordDAO.insertSelective(recordInsert);

    }

    /**
     * 取消主动授权
     */
    @Override
    public void cancelAuth(CancelAuthRequest request) {
        String bizId = request.getBizId();
        String bizType = request.getBizType();
        String mpiId = request.getMpiId();

        AcApplyRecordEntity query = new AcApplyRecordEntity();
        query.setBizId(bizId);
        query.setBizType(bizType);
        query.setMpiId(mpiId);
        List<AcApplyRecordEntity> records = acApplyRecordDAO.selectList(query);

        //删除对应的授权记录
        if (!CollectionUtils.isEmpty(records)) {
            records.forEach(e -> acDoctorAuthDAO.remove(e.getAuthId()));
        }
    }

    /**
     * 获取授权所需要的患者信息
     */
    @RpcService
    public AuthPatientInfoVo getAuthPatientInfo(AuthPatientInfoDto dto){
        String orgId = dto.getOrgId();
        String orgCode = dto.getOrgCode();
        String patientId = dto.getPatientId();
        if((StringUtils.isEmpty(orgId) && StringUtils.isEmpty(orgCode)) || StringUtils.isEmpty(patientId)){
            throw new ServiceException("缺少必要参数");
        }
        AuthPatientInfoVo rtn = new AuthPatientInfoVo();
        if(StringUtils.isEmpty(orgId)) {
            try {
                orgId = organizationService.getOrgIdByOrgCode(orgCode);
            } catch (ControllerException e) {
                logger.error("获取机构信息失败", e);
                return rtn;
            }
        }
        if(StringUtils.isEmpty(orgCode)) {
            try {
                Organization org = organizationService.getOrgDetailByOrgId(orgId);
                orgCode = org.getLocalOrgId();
            } catch (ControllerException e) {
                logger.error("获取机构信息失败", e);
                return rtn;
            }
        }

        //首先根据orgid 和 患者code 获取 健康通就诊人信息
        Map<String, Object> map = null;
        try {
            map = (Map<String, Object>) Client.rpcInvoke("pcn.mpiIdentityService", "findUserByPatientCode", orgId, patientId);
            if (CommonUtils.isNotEmpty(map)){
                rtn.setMpiId(String.valueOf(map.get("mpiId")));
                rtn.setLocalPhone(String.valueOf(map.get("phoneNo")));
                return rtn;
            }
        } catch (Exception e) {
            logger.error("获取就诊人失败", e);
        }

        //获取不到, 根据患者code 去his查询患者手机号
        QueryPatientListQO qo = new QueryPatientListQO();
        qo.setQueryType("1");
        qo.setSourcePatientId(patientId);
        qo.setVisitOrganization(orgCode);
        qo.setPageNo("1");
        qo.setPageSize("1");
        PageInfo<QueryPatientListVO> page = null;
        try {
            page = inpatientService.queryPatientList(qo);
        } catch (ControllerException e) {
            logger.error("查询his患者失败", e);
            return rtn;
        }
        if(Objects.nonNull(page) && !CollectionUtils.isEmpty(page.getList())) {
            QueryPatientListVO vo = page.getList().get(0);
            String patientPhone = vo.getPatientPhone();
            rtn.setHisPhone(patientPhone);
        }
        return rtn;

    }

}
